#import <QuartzCore/QuartzCore.h>
#import "EAGLView.h"

#define MAX_FRAMERATE 60
#define MIN_FRAMERATE 15
#define UPDATE_INTERVAL (1.0/MAX_FRAMERATE)
#define MAX_CYCLE_PER_FRAME (MAX_FRAMERATE/MIN_FRAMERATE)

@implementation EAGLView


// You must implement this method
+ (Class)layerClass
{
    return [CAEAGLLayer class];
}

//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:.
- (id)initWithCoder:(NSCoder*)coder
{
	lastTime = cyclesLeft = 0.0;
    self = [super initWithCoder:coder];
	if (self)
    {
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
        eaglLayer.opaque = TRUE;
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
                                        kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
                                        nil];
    }
	
	renderer = [[BasicRenderer alloc] init];
	if (!renderer)
	{
		[self release];
		return nil;
	}
	
	
	sharedGameController = [GameController sharedGameController];
    return self;
	
}


- (void) gameLoop
{
	double currentTime = CACurrentMediaTime();
	double update = (currentTime - lastTime) + cyclesLeft;
	
	
	if(update > MAX_CYCLE_PER_FRAME * UPDATE_INTERVAL)
		update = MAX_CYCLE_PER_FRAME * UPDATE_INTERVAL;


	while (update >= UPDATE_INTERVAL)
	{
		update -= UPDATE_INTERVAL;
		[sharedGameController updateSceneWithDelta: UPDATE_INTERVAL];
	}
	
	cyclesLeft = update;
	lastTime = currentTime;
	[self drawView:nil];
	
}

- (void) drawView:(id)sender
{
	//[sharedGameController renderScene];
	[renderer render];
}

- (void) layoutSubviews
{
	[renderer resizeFromLayer:(CAEAGLLayer*)self.layer];
    [self drawView:nil];
}

- (NSInteger) animationFrameInterval
{
	return animationFrameInterval;
}

- (void) setAnimationFrameInterval:(NSInteger)frameInterval
{
	// Frame interval defines how many display frames must pass between each time the
	// display link fires. The display link will only fire 30 times a second when the
	// frame internal is two on a display that refreshes 60 times a second. The default
	// frame interval setting of one will fire 60 times a second when the display refreshes
	// at 60 times a second. A frame interval setting of less than one results in undefined
	// behavior.
	if (frameInterval >= 1)
	{
		animationFrameInterval = frameInterval;
		[self stopAnimation];
		[self startAnimation];
	}
}

- (void) startAnimation
{
	
	displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(gameLoop)];
	[displayLink setFrameInterval:animationFrameInterval];
	[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
	
	//lastTime = CFAbsoluteTimeGetCurrent();
}



- (void)stopAnimation
{
	[displayLink invalidate];
	displayLink = nil;
}



- (void)dealloc
{   
    [renderer release];
    [super dealloc];
}






@end
